float4x4 g_mWorldViewProjection;
float skyZBias;
float scale = 0.03;

float4 cloudColor = float4(1, 1, 1, 1);
float4 skyColor = float4(0, 0.4966f, 1, 1);
float noiseScale = 4.1;
float noiseBias = -1.0;
float4 lightDir = float4(0, 1, 0, 1);
float4 sunColor = float4(1, 0.8244, 0.4399, 1);
float sunFallOff = 3.5;
float sunSharpness = 0.42;
float cloudSpeed = 0.052;
float noiseSpeed = 0.022;
float time_0_X;
texture g_NoiseTexture;

sampler3D NoiseTextureSampler =
sampler_state {
    Texture = <g_NoiseTexture>;
    MinFilter = Anisotropic;
    MagFilter = LINEAR;
    MipFilter = LINEAR;
    AddressU = WRAP;
    AddressV = WRAP;
    AddressW = WRAP;
};

struct VS_OUTPUT {
float4 Pos:
    POSITION;
float3 texCoord:
    TEXCOORD0;
};

VS_OUTPUT RenderSkyBoxVS(float4 Pos: POSITION) {
    VS_OUTPUT Out = (VS_OUTPUT)0;

    // Get the sky in place
    Pos.y += skyZBias;
    Out.Pos = mul(Pos, g_mWorldViewProjection);
    // Pass position to the fragment shader
    Out.texCoord = Pos.xyz * scale;

    return Out;
}

struct PS_OUTPUT {
float4 RGBColor :
    COLOR0;  // Pixel color
};

PS_OUTPUT RenderSkyBoxPS(float3 texCoord: TEXCOORD0) {
    // Create a sun
    PS_OUTPUT Output = (PS_OUTPUT)0;
    float3 l = lightDir - normalize(texCoord);
    float sun = saturate(sunFallOff * pow(dot(l, l), sunSharpness));
    float4 sky = lerp(sunColor, skyColor, sun);

    // Clouds are basically noise, we just need to scale and bias it.
    texCoord.xy += cloudSpeed * time_0_X;
    texCoord.z  += noiseSpeed * time_0_X;
    float noisy = tex3D(NoiseTextureSampler, texCoord).r;

    float lrp = noiseScale * noisy + noiseBias;

    Output.RGBColor = lerp(cloudColor, sky, saturate(lrp));
    return Output;
}

technique RenderSkyBox {
    pass P0
    {
        VertexShader = compile vs_3_0 RenderSkyBoxVS();
        PixelShader  = compile ps_3_0 RenderSkyBoxPS();
    }
}
